/*
Copyright 2024 MySQL Parser Project

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package sqlparser

import (
	"errors"
	"fmt"
	"strings"
)

// Parser represents a SQL parser
type Parser struct {
	version        string
	truncateUILen  int
	truncateErrLen int
}

// Options represents parser options
type Options struct {
	MySQLServerVersion string
	TruncateUILen      int
	TruncateErrLen     int
}

// New creates a new parser with the given options
func New(opts Options) (*Parser, error) {
	if opts.MySQLServerVersion == "" {
		opts.MySQLServerVersion = "5.7.0"
	}
	
	convVersion, err := ConvertMySQLVersionToCommentVersion(opts.MySQLServerVersion)
	if err != nil {
		return nil, err
	}
	
	return &Parser{
		version:        convVersion,
		truncateUILen:  opts.TruncateUILen,
		truncateErrLen: opts.TruncateErrLen,
	}, nil
}

// Parse parses a SQL string and returns the AST
func (p *Parser) Parse(sql string) (Statement, error) {
	tokenizer := NewStringTokenizer(sql)
	if yyParse(tokenizer) != 0 {
		if tokenizer.lastError != nil {
			return nil, tokenizer.lastError
		}
		return nil, errors.New("syntax error")
	}
	return tokenizer.ParseTree, nil
}

// Parse2 parses a SQL string and returns the AST and bind variables
func (p *Parser) Parse2(sql string) (Statement, BindVars, error) {
	tokenizer := NewStringTokenizer(sql)
	if yyParse(tokenizer) != 0 {
		if tokenizer.lastError != nil {
			return nil, nil, tokenizer.lastError
		}
		return nil, nil, errors.New("syntax error")
	}
	return tokenizer.ParseTree, make(BindVars), nil
}

// ParseExpr parses an expression and returns the AST
func (p *Parser) ParseExpr(sql string) (Expr, error) {
	tokenizer := NewStringTokenizer(sql)
	expr, err := parseExpr(tokenizer)
	if err != nil {
		return nil, err
	}
	return expr, nil
}

// ConvertMySQLVersionToCommentVersion converts MySQL version to comment version format
func ConvertMySQLVersionToCommentVersion(version string) (string, error) {
	parts := strings.Split(version, ".")
	if len(parts) < 2 {
		return "", fmt.Errorf("invalid MySQL version format: %s", version)
	}
	
	major := parts[0]
	minor := parts[1]
	patch := "0"
	if len(parts) > 2 {
		patch = parts[2]
	}
	
	return fmt.Sprintf("%s%02s%02s", major, minor, patch), nil
}

// BindVars represents bind variables
type BindVars map[string]interface{}

// yyParse is a placeholder for the actual yacc-generated parser
// In a real implementation, this would be generated by yacc/bison
func yyParse(tokenizer *Tokenizer) int {
	// This is a simplified parser implementation
	// In a real implementation, this would be generated by yacc/bison
	return parseStatement(tokenizer)
}

// parseStatement parses a single statement
func parseStatement(tokenizer *Tokenizer) int {
	tok, val := tokenizer.Scan()
	if tok == 0 {
		return 0 // EOF
	}
	
	switch tok {
	case int(SELECT):
		stmt, err := parseSelect(tokenizer)
		if err != nil {
			tokenizer.lastError = err
			return 1
		}
		tokenizer.ParseTree = stmt
		return 0
	case int(INSERT):
		stmt, err := parseInsert(tokenizer)
		if err != nil {
			tokenizer.lastError = err
			return 1
		}
		tokenizer.ParseTree = stmt
		return 0
	case int(UPDATE):
		stmt, err := parseUpdate(tokenizer)
		if err != nil {
			tokenizer.lastError = err
			return 1
		}
		tokenizer.ParseTree = stmt
		return 0
	case int(DELETE):
		stmt, err := parseDelete(tokenizer)
		if err != nil {
			tokenizer.lastError = err
			return 1
		}
		tokenizer.ParseTree = stmt
		return 0
	case int(CREATE):
		stmt, err := parseCreate(tokenizer)
		if err != nil {
			tokenizer.lastError = err
			return 1
		}
		tokenizer.ParseTree = stmt
		return 0
	case int(ALTER):
		stmt, err := parseAlter(tokenizer)
		if err != nil {
			tokenizer.lastError = err
			return 1
		}
		tokenizer.ParseTree = stmt
		return 0
	case int(DROP):
		stmt, err := parseDrop(tokenizer)
		if err != nil {
			tokenizer.lastError = err
			return 1
		}
		tokenizer.ParseTree = stmt
		return 0
	case int(TRUNCATE):
		stmt, err := parseTruncate(tokenizer)
		if err != nil {
			tokenizer.lastError = err
			return 1
		}
		tokenizer.ParseTree = stmt
		return 0
	case int(BEGIN):
		stmt, err := parseBegin(tokenizer)
		if err != nil {
			tokenizer.lastError = err
			return 1
		}
		tokenizer.ParseTree = stmt
		return 0
	case int(COMMIT):
		stmt, err := parseCommit(tokenizer)
		if err != nil {
			tokenizer.lastError = err
			return 1
		}
		tokenizer.ParseTree = stmt
		return 0
	case int(ROLLBACK):
		stmt, err := parseRollback(tokenizer)
		if err != nil {
			tokenizer.lastError = err
			return 1
		}
		tokenizer.ParseTree = stmt
		return 0
	default:
		tokenizer.lastError = fmt.Errorf("unexpected token: %s", val)
		return 1
	}
}

// parseSelect parses a SELECT statement
func parseSelect(tokenizer *Tokenizer) (*Select, error) {
	sel := &Select{}
	
	// Check for DISTINCT
	tok, _ := tokenizer.Scan()
	if tok == int(DISTINCT) {
		sel.Distinct = true
	} else {
		tokenizer.PushBack()
	}
	
	// Parse SELECT expressions
	exprs, err := parseSelectExprs(tokenizer)
	if err != nil {
		return nil, err
	}
	sel.SelectExprs = exprs
	
	// Check for FROM clause
	tok, _ = tokenizer.Scan()
	if tok == int(FROM) {
		tableExprs, err := parseTableExprs(tokenizer)
		if err != nil {
			return nil, err
		}
		sel.From = tableExprs
	} else {
		if tok != 0 {
			tokenizer.PushBack()
		}
	}
	
	// Parse WHERE clause
	tok, _ = tokenizer.Scan()
	if tok == int(WHERE) {
		where, err := parseExpr(tokenizer)
		if err != nil {
			return nil, err
		}
		sel.Where = &Where{Type: WhereStr, Expr: where}
	} else {
		if tok != 0 {
			tokenizer.PushBack()
		}
	}
	
	// Parse GROUP BY clause
	tok, _ = tokenizer.Scan()
	if tok == int(GROUP) {
		tok, _ = tokenizer.Scan()
		if tok == int(BY) {
			groupBy, err := parseGroupBy(tokenizer)
			if err != nil {
				return nil, err
			}
			sel.GroupBy = groupBy
		} else {
			return nil, fmt.Errorf("expected BY after GROUP")
		}
	} else {
		if tok != 0 {
			tokenizer.PushBack()
		}
	}
	
	// Parse HAVING clause
	tok, _ = tokenizer.Scan()
	if tok == int(HAVING) {
		having, err := parseExpr(tokenizer)
		if err != nil {
			return nil, err
		}
		sel.Having = &Where{Type: HavingStr, Expr: having}
	} else {
		if tok != 0 {
			tokenizer.PushBack()
		}
	}
	
	// Parse ORDER BY clause
	tok, _ = tokenizer.Scan()
	if tok == int(ORDER) {
		tok, _ = tokenizer.Scan()
		if tok == int(BY) {
			orderBy, err := parseOrderBy(tokenizer)
			if err != nil {
				return nil, err
			}
			sel.OrderBy = orderBy
		} else {
			return nil, fmt.Errorf("expected BY after ORDER")
		}
	} else {
		if tok != 0 {
			tokenizer.PushBack()
		}
	}
	
	// Parse LIMIT clause
	tok, _ = tokenizer.Scan()
	if tok == int(LIMIT) {
		limit, err := parseLimit(tokenizer)
		if err != nil {
			return nil, err
		}
		sel.Limit = limit
	} else {
		if tok != 0 {
			tokenizer.PushBack()
		}
	}
	
	return sel, nil
}

// parseInsert parses an INSERT statement
func parseInsert(tokenizer *Tokenizer) (*Insert, error) {
	ins := &Insert{}
	
	// Parse INTO keyword
	tok, _ := tokenizer.Scan()
	if tok != int(INTO) {
		return nil, errors.New("expected INTO after INSERT")
	}
	
	// Parse table name
	tok, val := tokenizer.Scan()
	if tok != int(ID) {
		return nil, errors.New("expected table name")
	}
	ins.Table = TableName{Name: NewIdentifierCS(val)}
	
	return ins, nil
}

// parseUpdate parses an UPDATE statement
func parseUpdate(tokenizer *Tokenizer) (*Update, error) {
	upd := &Update{}
	
	// Parse table name
	tok, val := tokenizer.Scan()
	if tok != int(ID) {
		return nil, errors.New("expected table name")
	}
	upd.TableExprs = []TableExpr{&AliasedTableExpr{
		Expr: TableName{Name: NewIdentifierCS(val)},
	}}
	
	return upd, nil
}

// parseDelete parses a DELETE statement
func parseDelete(tokenizer *Tokenizer) (*Delete, error) {
	del := &Delete{}
	
	// Parse FROM keyword
	tok, _ := tokenizer.Scan()
	if tok != int(FROM) {
		return nil, errors.New("expected FROM after DELETE")
	}
	
	// Parse table expressions
	tableExprs, err := parseTableExprs(tokenizer)
	if err != nil {
		return nil, err
	}
	del.TableExprs = tableExprs
	
	return del, nil
}

// parseSelectExprs parses SELECT expressions
func parseSelectExprs(tokenizer *Tokenizer) (SelectExprs, error) {
	var exprs SelectExprs
	
	for {
		expr, err := parseSelectExpr(tokenizer)
		if err != nil {
			return nil, err
		}
		exprs = append(exprs, expr)
		
		tok, _ := tokenizer.Scan()
		if tok != int(COMMA) {
			// Put back the token
			tokenizer.PushBack()
			break
		}
	}
	
	return exprs, nil
}

// parseSelectExpr parses a single SELECT expression with optional alias
func parseSelectExpr(tokenizer *Tokenizer) (SelectExpr, error) {
	expr, err := parseExpr(tokenizer)
	if err != nil {
		return nil, err
	}
	
	// Check for alias
	tok, val := tokenizer.Scan()
	aliasedExpr := &AliasedExpr{Expr: expr}
	
	if tok == int(AS) {
		// AS keyword followed by alias
		tok, val = tokenizer.Scan()
		if tok == int(ID) {
			aliasedExpr.As = IdentifierCI{val: val}
		} else {
			return nil, errors.New("expected identifier after AS")
		}
	} else if tok == int(ID) {
		// Direct alias without AS keyword
		aliasedExpr.As = IdentifierCI{val: val}
	} else {
		// No alias, put back the token
		tokenizer.PushBack()
	}
	
	return aliasedExpr, nil
}

// parseTableExprs parses table expressions
func parseTableExprs(tokenizer *Tokenizer) (TableExprs, error) {
	var exprs TableExprs
	
	// Parse first table expression
	expr, err := parseTableExpr(tokenizer)
	if err != nil {
		return nil, err
	}
	
	// Check for JOIN clauses
	for {
		tok, _ := tokenizer.Scan()
		if tok == int(JOIN) || tok == int(INNER) || tok == int(LEFT) || tok == int(RIGHT) {
			// Parse JOIN expression
			joinExpr, err := parseJoinExpr(tokenizer, expr, tok)
			if err != nil {
				return nil, err
			}
			expr = joinExpr
		} else if tok == int(COMMA) {
			// Comma join (cross join)
			rightExpr, err := parseTableExpr(tokenizer)
			if err != nil {
				return nil, err
			}
			expr = &JoinTableExpr{
				LeftExpr:  expr,
				Join:      "cross join",
				RightExpr: rightExpr,
			}
		} else {
			tokenizer.PushBack()
			break
		}
	}
	
	exprs = append(exprs, expr)
	return exprs, nil
}

// parseTableExpr parses a single table expression
func parseTableExpr(tokenizer *Tokenizer) (TableExpr, error) {
	tok, val := tokenizer.Scan()
	if tok == int(LPAREN) {
		// Subquery
		subquery, err := parseSelect(tokenizer)
		if err != nil {
			return nil, err
		}
		tok, _ = tokenizer.Scan()
		if tok != int(RPAREN) {
			return nil, errors.New("expected closing parenthesis after subquery")
		}
		
		// Check for alias
		tok, alias := tokenizer.Scan()
		if tok == int(AS) {
			tok, alias = tokenizer.Scan()
		}
		if tok == int(ID) {
			return &AliasedTableExpr{
				Expr: &Subquery{Select: subquery},
				As:   IdentifierCS{val: alias},
			}, nil
		} else {
			tokenizer.PushBack()
			return &AliasedTableExpr{
				Expr: &Subquery{Select: subquery},
			}, nil
		}
	} else if tok == int(ID) {
		// Table name
		tableName := TableName{Name: IdentifierCS{val: val}}
		
		// Check for alias
		tok, alias := tokenizer.Scan()
		if tok == int(AS) {
			tok, alias = tokenizer.Scan()
		}
		if tok == int(ID) {
			return &AliasedTableExpr{
				Expr: tableName,
				As:   IdentifierCS{val: alias},
			}, nil
		} else {
			tokenizer.PushBack()
			return &AliasedTableExpr{
				Expr: tableName,
			}, nil
		}
	} else {
		return nil, errors.New("expected table name or subquery")
	}
}

// parseJoinExpr parses JOIN expressions
func parseJoinExpr(tokenizer *Tokenizer, leftExpr TableExpr, joinType int) (TableExpr, error) {
	var joinStr string
	
	switch joinType {
	case int(JOIN):
		joinStr = "join"
	case int(INNER):
		// Expect JOIN after INNER
		tok, _ := tokenizer.Scan()
		if tok != int(JOIN) {
			return nil, errors.New("expected JOIN after INNER")
		}
		joinStr = "inner join"
	case int(LEFT):
		// Expect JOIN after LEFT
		tok, _ := tokenizer.Scan()
		if tok == int(OUTER) {
			tok, _ = tokenizer.Scan()
		}
		if tok != int(JOIN) {
			return nil, errors.New("expected JOIN after LEFT")
		}
		joinStr = "left join"
	case int(RIGHT):
		// Expect JOIN after RIGHT
		tok, _ := tokenizer.Scan()
		if tok == int(OUTER) {
			tok, _ = tokenizer.Scan()
		}
		if tok != int(JOIN) {
			return nil, errors.New("expected JOIN after RIGHT")
		}
		joinStr = "right join"

	default:
		return nil, errors.New("unknown join type")
	}
	
	// Parse right table expression
	rightExpr, err := parseTableExpr(tokenizer)
	if err != nil {
		return nil, err
	}
	
	// Parse join condition
	tok, _ := tokenizer.Scan()
	var condition JoinCondition
	if tok == int(ON) {
		// ON condition
		expr, err := parseExpr(tokenizer)
		if err != nil {
			return nil, err
		}
		condition = &OnCondition{Expr: expr}
	} else if tok == int(USING) {
		// USING condition
		tok, _ = tokenizer.Scan()
		if tok != int(LPAREN) {
			return nil, errors.New("expected opening parenthesis after USING")
		}
		
		var cols Columns
		for {
			tok, val := tokenizer.Scan()
			if tok != int(ID) {
				return nil, errors.New("expected column name")
			}
			cols = append(cols, IdentifierCI{val: val})
			
			tok, _ = tokenizer.Scan()
			if tok == int(RPAREN) {
				break
			} else if tok != int(COMMA) {
				return nil, errors.New("expected comma or closing parenthesis")
			}
		}
		
		condition = &UsingCondition{Cols: cols}
	} else {
		// No condition (cross join)
		tokenizer.PushBack()
	}
	
	return &JoinTableExpr{
		LeftExpr:  leftExpr,
		Join:      joinStr,
		RightExpr: rightExpr,
		Condition: condition,
	}, nil
}

// parseExpr parses an expression with full operator precedence
func parseExpr(tokenizer *Tokenizer) (Expr, error) {
	return parseOrExpr(tokenizer)
}

// parseOrExpr parses OR expressions (lowest precedence)
func parseOrExpr(tokenizer *Tokenizer) (Expr, error) {
	left, err := parseAndExpr(tokenizer)
	if err != nil {
		return nil, err
	}
	
	for {
		tok, _ := tokenizer.Scan()
		if tok != int(OR) {
			tokenizer.PushBack()
			break
		}
		
		right, err := parseAndExpr(tokenizer)
		if err != nil {
			return nil, err
		}
		
		left = &BinaryExpr{
			Left:     left,
			Operator: OrStr,
			Right:    right,
		}
	}
	
	return left, nil
}

// parseAndExpr parses AND expressions
func parseAndExpr(tokenizer *Tokenizer) (Expr, error) {
	left, err := parseComparisonExpr(tokenizer)
	if err != nil {
		return nil, err
	}
	
	for {
		tok, _ := tokenizer.Scan()
		if tok != int(AND) {
			tokenizer.PushBack()
			break
		}
		
		right, err := parseComparisonExpr(tokenizer)
		if err != nil {
			return nil, err
		}
		
		left = &BinaryExpr{
			Left:     left,
			Operator: AndStr,
			Right:    right,
		}
	}
	
	return left, nil
}

// parseComparisonExpr parses comparison expressions (=, !=, <, >, etc.)
func parseComparisonExpr(tokenizer *Tokenizer) (Expr, error) {
	left, err := parseArithmeticExpr(tokenizer)
	if err != nil {
		return nil, err
	}
	
	tok, _ := tokenizer.Scan()
	var operator string
	
	switch tok {
	case int(EQ), int(EQUAL):
		operator = EqualStr
	case int(NE):
		operator = NotEqualStr
	case int(LT), int(LESS):
		operator = LessThanStr
	case int(LE):
		operator = LessEqualStr
	case int(GT), int(GREATER):
		operator = GreaterThanStr
	case int(GE):
		operator = GreaterEqualStr
	case int(LIKE):
		operator = LikeStr
	case int(IN):
		// Special handling for IN operator
		nextTok, _ := tokenizer.Scan()
		if nextTok == int(LPAREN) {
			// Parse what's inside the parentheses
			right, err := parseParenthesizedExpr(tokenizer)
			if err != nil {
				return nil, err
			}
			return &BinaryExpr{
				Left:     left,
				Operator: InStr,
				Right:    right,
			}, nil
		} else {
			tokenizer.PushBack()
			right, err := parseArithmeticExpr(tokenizer)
			if err != nil {
				return nil, err
			}
			return &BinaryExpr{
				Left:     left,
				Operator: InStr,
				Right:    right,
			}, nil
		}
	case int(IS):
		operator = IsStr
	default:
		tokenizer.PushBack()
		return left, nil
	}
	
	right, err := parseArithmeticExpr(tokenizer)
	if err != nil {
		return nil, err
	}
	
	return &BinaryExpr{
		Left:     left,
		Operator: operator,
		Right:    right,
	}, nil
}

// parseArithmeticExpr parses arithmetic expressions (+, -, *, /, %)
func parseArithmeticExpr(tokenizer *Tokenizer) (Expr, error) {
	left, err := parsePrimaryExpr(tokenizer)
	if err != nil {
		return nil, err
	}
	
	for {
		tok, _ := tokenizer.Scan()
		var operator string
		
		switch tok {
		case int(PLUS), int(PLUS_SIGN):
			operator = PlusStr
		case int(MINUS), int(MINUS_SIGN):
			operator = MinusStr
		case int(MULT), int(MULT_SIGN):
			operator = MultStr
		case int(DIV), int(DIV_SIGN):
			operator = DivStr
		case int(MOD), int(MOD_SIGN):
			operator = ModStr
		default:
			tokenizer.PushBack()
			return left, nil
		}
		
		right, err := parsePrimaryExpr(tokenizer)
		if err != nil {
			return nil, err
		}
		
		left = &BinaryExpr{
			Left:     left,
			Operator: operator,
			Right:    right,
		}
	}
}

// parsePrimaryExpr parses primary expressions (literals, identifiers, functions, etc.)
func parsePrimaryExpr(tokenizer *Tokenizer) (Expr, error) {
	tok, val := tokenizer.Scan()
	
	switch tok {
	case int(MULT_SIGN), int(MULT):
		// Handle * (star expression)
		return &StarExpr{}, nil
		
	case int(ID):
		// Check if this is a function call
		nextTok, _ := tokenizer.Scan()
		if nextTok == int(LPAREN) {
			return parseFunctionCall(tokenizer, val)
		} else {
			tokenizer.PushBack()
			return &ColName{Name: IdentifierCI{val: val}}, nil
		}
		
	case int(STRING):
		return &Literal{Type: StrVal, Val: val}, nil
		
	case int(INTEGRAL):
		return &Literal{Type: IntVal, Val: val}, nil
		
	case int(FLOAT):
		return &Literal{Type: FloatVal, Val: val}, nil
		
	case int(NULL):
		return &NullVal{}, nil
		
	case int(TRUE):
		return &BoolVal{Val: true}, nil
		
	case int(FALSE):
		return &BoolVal{Val: false}, nil
		
	case int(LPAREN):
		// Handle parenthesized expressions or subqueries
		return parseParenthesizedExpr(tokenizer)
		
	case int(CASE):
		// Handle CASE expressions
		return parseCaseExpr(tokenizer)
		
	default:
		return nil, fmt.Errorf("unexpected token in expression: %s", val)
	}
}

// DDL parsing functions

// parseCreate parses CREATE statements
func parseCreate(tokenizer *Tokenizer) (Statement, error) {
	tok, _ := tokenizer.Scan()
	switch tok {
	case int(TABLE):
		return parseCreateTable(tokenizer)
	case int(TEMPORARY):
		// For CREATE TEMPORARY TABLE, we need to check the next token
		nextTok, _ := tokenizer.Scan()
		if nextTok == int(TABLE) {
			return parseCreateTableWithTemporary(tokenizer)
		}
		return nil, errors.New("expected TABLE after TEMPORARY")
	case int(INDEX):
		return parseCreateIndex(tokenizer)
	case int(UNIQUE):
		// For CREATE UNIQUE INDEX, we need to check the next token
		nextTok, _ := tokenizer.Scan()
		if nextTok == int(INDEX) {
			return parseCreateUniqueIndex(tokenizer)
		}
		return nil, errors.New("expected INDEX after UNIQUE")
	default:
		return nil, errors.New("unsupported CREATE statement")
	}
}

// parseCreateTable parses CREATE TABLE statements
func parseCreateTable(tokenizer *Tokenizer) (*CreateTableStatement, error) {
	stmt := &CreateTableStatement{}
	
	// Check for IF NOT EXISTS
	tok, val := tokenizer.Scan()
	if tok == int(IF) {
		tok, val = tokenizer.Scan()
		if tok == int(NOT) {
			tok, val = tokenizer.Scan()
			if tok == int(EXISTS) {
				stmt.IfNotExists = true
				tok, val = tokenizer.Scan()
			}
		}
	}
	
	// Parse table name
	if tok == int(ID) {
		// val already contains the table name
		stmt.Table = &TableName{Name: NewIdentifierCS(val)}
	} else {
		return nil, fmt.Errorf("expected table name, got token %d with value '%s'", tok, val)
	}
	
	// For now, return a basic CREATE TABLE statement
	return stmt, nil
}

// parseCreateTableWithTemporary parses CREATE TEMPORARY TABLE statements
func parseCreateTableWithTemporary(tokenizer *Tokenizer) (*CreateTableStatement, error) {
	stmt := &CreateTableStatement{}
	stmt.Temporary = true
	
	// Check for IF NOT EXISTS
	tok, val := tokenizer.Scan()
	if tok == int(IF) {
		tok, val = tokenizer.Scan()
		if tok == int(NOT) {
			tok, val = tokenizer.Scan()
			if tok == int(EXISTS) {
				stmt.IfNotExists = true
				tok, val = tokenizer.Scan()
			}
		}
	}
	
	// Parse table name
	if tok == int(ID) {
		// val already contains the table name
		stmt.Table = &TableName{Name: NewIdentifierCS(val)}
	} else {
		return nil, fmt.Errorf("expected table name, got token %d with value '%s'", tok, val)
	}
	
	// For now, return a basic CREATE TABLE statement
	return stmt, nil
}

// parseCreateIndex parses CREATE INDEX statements
func parseCreateIndex(tokenizer *Tokenizer) (*CreateIndexStatement, error) {
	stmt := &CreateIndexStatement{}
	
	// Parse index name
	tok, val := tokenizer.Scan()
	if tok == int(ID) {
		stmt.Index = val
	} else {
		return nil, fmt.Errorf("expected index name, got token %d with value '%s'", tok, val)
	}
	
	// Expect ON
	tok, val = tokenizer.Scan()
	if tok != int(ON) {
		return nil, fmt.Errorf("expected ON, got token %d with value '%s'", tok, val)
	}
	
	// Parse table name
	tok, val = tokenizer.Scan()
	if tok == int(ID) {
		stmt.Table = &TableName{Name: NewIdentifierCS(val)}
	} else {
		return nil, fmt.Errorf("expected table name, got token %d with value '%s'", tok, val)
	}
	
	return stmt, nil
}

// parseCreateUniqueIndex parses CREATE UNIQUE INDEX statements
func parseCreateUniqueIndex(tokenizer *Tokenizer) (*CreateIndexStatement, error) {
	stmt := &CreateIndexStatement{}
	stmt.Unique = true
	
	// Check for IF NOT EXISTS
	tok, val := tokenizer.Scan()
	if tok == int(IF) {
		tok, val = tokenizer.Scan()
		if tok == int(NOT) {
			tok, val = tokenizer.Scan()
			if tok == int(EXISTS) {
				stmt.IfNotExists = true
				tok, val = tokenizer.Scan()
			} else {
				return nil, fmt.Errorf("expected EXISTS after IF NOT, got token %d with value '%s'", tok, val)
			}
		} else {
			return nil, fmt.Errorf("expected NOT after IF, got token %d with value '%s'", tok, val)
		}
	}
	
	// Parse index name
	if tok == int(ID) {
		stmt.Index = val
	} else {
		return nil, fmt.Errorf("expected index name, got token %d with value '%s'", tok, val)
	}
	
	// Expect ON
	tok, val = tokenizer.Scan()
	if tok != int(ON) {
		return nil, fmt.Errorf("expected ON, got token %d with value '%s'", tok, val)
	}
	
	// Parse table name
	tok, val = tokenizer.Scan()
	if tok == int(ID) {
		stmt.Table = &TableName{Name: NewIdentifierCS(val)}
	} else {
		return nil, fmt.Errorf("expected table name, got token %d with value '%s'", tok, val)
	}
	
	return stmt, nil
}

// parseAlter parses ALTER statements
func parseAlter(tokenizer *Tokenizer) (Statement, error) {
	tok, _ := tokenizer.Scan()
	if tok == int(TABLE) {
		return parseAlterTable(tokenizer)
	}
	return nil, errors.New("unsupported ALTER statement")
}

// parseAlterTable parses ALTER TABLE statements
func parseAlterTable(tokenizer *Tokenizer) (*AlterTableStatement, error) {
	stmt := &AlterTableStatement{}
	
	// Parse table name
	tok, val := tokenizer.Scan()
	if tok == int(ID) {
		stmt.Table = &TableName{Name: NewIdentifierCS(val)}
	} else {
		return nil, fmt.Errorf("expected table name, got token %d with value '%s'", tok, val)
	}
	
	// For now, return a basic ALTER TABLE statement
	return stmt, nil
}

// parseDrop parses DROP statements
func parseDrop(tokenizer *Tokenizer) (Statement, error) {
	tok, _ := tokenizer.Scan()
	switch tok {
	case int(TABLE):
		return parseDropTable(tokenizer)
	case int(TEMPORARY):
		// For DROP TEMPORARY TABLE, we need to check the next token
		nextTok, _ := tokenizer.Scan()
		if nextTok == int(TABLE) {
			return parseDropTableWithTemporary(tokenizer)
		}
		return nil, errors.New("expected TABLE after TEMPORARY")
	case int(INDEX):
		return parseDropIndex(tokenizer)
	default:
		return nil, errors.New("unsupported DROP statement")
	}
}

// parseDropTable parses DROP TABLE statements
func parseDropTable(tokenizer *Tokenizer) (*DropTableStatement, error) {
	stmt := &DropTableStatement{}
	
	// Check for IF EXISTS
	tok, val := tokenizer.Scan()
	if tok == int(IF) {
		tok, val = tokenizer.Scan()
		if tok == int(EXISTS) {
			stmt.IfExists = true
			tok, val = tokenizer.Scan()
		}
	}
	
	// Parse table name(s)
	if tok == int(ID) {
		stmt.Tables = []*TableName{{Name: NewIdentifierCS(val)}}
	} else {
		return nil, fmt.Errorf("expected table name, got token %d with value '%s'", tok, val)
	}
	
	return stmt, nil
}

// parseDropTableWithTemporary parses DROP TEMPORARY TABLE statements
func parseDropTableWithTemporary(tokenizer *Tokenizer) (*DropTableStatement, error) {
	stmt := &DropTableStatement{}
	stmt.Temporary = true
	
	// Check for IF EXISTS
	tok, val := tokenizer.Scan()
	if tok == int(IF) {
		tok, val = tokenizer.Scan()
		if tok == int(EXISTS) {
			stmt.IfExists = true
			tok, val = tokenizer.Scan()
		}
	}
	
	// Parse table name(s)
	if tok == int(ID) {
		stmt.Tables = []*TableName{{Name: NewIdentifierCS(val)}}
	} else {
		return nil, fmt.Errorf("expected table name, got token %d with value '%s'", tok, val)
	}
	
	return stmt, nil
}

// parseDropIndex parses DROP INDEX statements
func parseDropIndex(tokenizer *Tokenizer) (*DropIndexStatement, error) {
	stmt := &DropIndexStatement{}
	
	// Parse index name
	tok, val := tokenizer.Scan()
	if tok == int(ID) {
		stmt.Index = val
	} else {
		return nil, fmt.Errorf("expected index name, got token %d with value '%s'", tok, val)
	}
	
	// Expect ON
	tok, val = tokenizer.Scan()
	if tok != int(ON) {
		return nil, fmt.Errorf("expected ON, got token %d with value '%s'", tok, val)
	}
	
	// Parse table name
	tok, val = tokenizer.Scan()
	if tok == int(ID) {
		stmt.Table = &TableName{Name: NewIdentifierCS(val)}
	} else {
		return nil, fmt.Errorf("expected table name, got token %d with value '%s'", tok, val)
	}
	
	return stmt, nil
}

// parseTruncate parses TRUNCATE statements
func parseTruncate(tokenizer *Tokenizer) (*TruncateStatement, error) {
	stmt := &TruncateStatement{}
	
	// Expect TABLE
	tok, val := tokenizer.Scan()
	if tok != int(TABLE) {
		return nil, fmt.Errorf("expected TABLE, got token %d with value '%s'", tok, val)
	}
	
	// Parse table name
	tok, val = tokenizer.Scan()
	if tok == int(ID) {
		stmt.Table = &TableName{Name: NewIdentifierCS(val)}
	} else {
		return nil, fmt.Errorf("expected table name, got token %d with value '%s'", tok, val)
	}
	
	return stmt, nil
}

// parseGroupBy parses GROUP BY clause
func parseGroupBy(tokenizer *Tokenizer) (GroupBy, error) {
	var groupBy GroupBy
	
	for {
		expr, err := parseExpr(tokenizer)
		if err != nil {
			return nil, err
		}
		groupBy = append(groupBy, expr)
		
		tok, _ := tokenizer.Scan()
		if tok != int(COMMA) {
			tokenizer.PushBack()
			break
		}
	}
	
	return groupBy, nil
}

// parseOrderBy parses ORDER BY clause
func parseOrderBy(tokenizer *Tokenizer) (OrderBy, error) {
	var orderBy OrderBy
	
	for {
		expr, err := parseExpr(tokenizer)
		if err != nil {
			return nil, err
		}
		
		order := &Order{Expr: expr, Direction: AscScr}
		
		tok, _ := tokenizer.Scan()
		if tok == int(ASC) {
			order.Direction = AscScr
		} else if tok == int(DESC) {
			order.Direction = DescScr
		} else {
			tokenizer.PushBack()
		}
		
		orderBy = append(orderBy, order)
		
		tok, _ = tokenizer.Scan()
		if tok != int(COMMA) {
			tokenizer.PushBack()
			break
		}
	}
	
	return orderBy, nil
}

// parseLimit parses LIMIT clause
func parseLimit(tokenizer *Tokenizer) (*Limit, error) {
	limit := &Limit{}
	
	// Parse first number (could be offset or rowcount)
	first, err := parseExpr(tokenizer)
	if err != nil {
		return nil, err
	}
	
	// Check for OFFSET keyword or comma
	tok, _ := tokenizer.Scan()
	if tok == int(COMMA) {
		// First number is offset, parse rowcount
		limit.Offset = first
		rowcount, err := parseExpr(tokenizer)
		if err != nil {
			return nil, err
		}
		limit.Rowcount = rowcount
	} else if tok == int(OFFSET) {
		// First number is rowcount, parse offset
		limit.Rowcount = first
		offset, err := parseExpr(tokenizer)
		if err != nil {
			return nil, err
		}
		limit.Offset = offset
	} else {
		// Only rowcount specified
		limit.Rowcount = first
		tokenizer.PushBack()
	}
	
	return limit, nil
}

// parseFunctionCall parses function calls
func parseFunctionCall(tokenizer *Tokenizer, name string) (Expr, error) {
	funcExpr := &FuncExpr{Name: IdentifierCI{val: name}}
	
	// Check for DISTINCT
	tok, _ := tokenizer.Scan()
	if tok == int(DISTINCT) {
		funcExpr.Distinct = true
	} else {
		tokenizer.PushBack()
	}
	
	// Parse arguments
	for {
		tok, _ := tokenizer.Scan()
		if tok == int(RPAREN) {
			break
		}
		tokenizer.PushBack()
		
		expr, err := parseExpr(tokenizer)
		if err != nil {
			return nil, err
		}
		
		// Wrap expr in AliasedExpr for SelectExprs
		aliasedExpr := &AliasedExpr{Expr: expr}
		funcExpr.Exprs = append(funcExpr.Exprs, aliasedExpr)
		
		tok, _ = tokenizer.Scan()
		if tok == int(RPAREN) {
			break
		} else if tok != int(COMMA) {
			return nil, errors.New("expected comma or closing parenthesis")
		}
	}
	
	return funcExpr, nil
}

// parseSubquery parses a subquery without recursion issues
func parseSubquery(tokenizer *Tokenizer) (*Select, error) {
	sel := &Select{}
	
	// Parse SELECT expressions
	selectExprs, err := parseSelectExprsForSubquery(tokenizer)
	if err != nil {
		return nil, err
	}
	sel.SelectExprs = selectExprs
	
	// Parse FROM clause
	tok, _ := tokenizer.Scan()
	if tok == int(FROM) {
		tableExprs, err := parseTableExprs(tokenizer)
		if err != nil {
			return nil, err
		}
		sel.From = tableExprs
	} else {
		tokenizer.PushBack()
	}
	
	// Parse WHERE clause
	tok, _ = tokenizer.Scan()
	if tok == int(WHERE) {
		where, err := parseExpr(tokenizer)
		if err != nil {
			return nil, err
		}
		sel.Where = &Where{Type: WhereStr, Expr: where}
	} else {
		tokenizer.PushBack()
	}
	
	return sel, nil
}

// parseSelectExprsForSubquery parses SELECT expressions for subqueries without recursion
func parseSelectExprsForSubquery(tokenizer *Tokenizer) (SelectExprs, error) {
	var selectExprs SelectExprs
	
	for {
		// Parse a simple select expression
		tok, val := tokenizer.Scan()
		var expr Expr
		
		switch tok {
		case int(MULT), int(MULT_SIGN):
			expr = &StarExpr{}
		case int(ID):
			// Check if this is a function call
			nextTok, _ := tokenizer.Scan()
			if nextTok == int(LPAREN) {
				funcExpr, err := parseFunctionCall(tokenizer, val)
				if err != nil {
					return nil, err
				}
				expr = funcExpr
			} else {
				tokenizer.PushBack()
				expr = &ColName{Name: IdentifierCI{val: val}}
			}
		default:
			return nil, fmt.Errorf("unexpected token in SELECT expression: %s", val)
		}
		
		selectExprs = append(selectExprs, &AliasedExpr{Expr: expr})
		
		tok, _ = tokenizer.Scan()
		if tok != int(COMMA) {
			tokenizer.PushBack()
			break
		}
	}
	
	return selectExprs, nil
}

// parseParenthesizedExpr parses parenthesized expressions or subqueries
func parseParenthesizedExpr(tokenizer *Tokenizer) (Expr, error) {
	// Check if this is a subquery (starts with SELECT)
	tok, _ := tokenizer.Scan()
	if tok == int(SELECT) {
		// Parse as subquery using specialized function
		subquery, err := parseSubquery(tokenizer)
		if err != nil {
			return nil, err
		}
		
		tok, _ := tokenizer.Scan()
		if tok != int(RPAREN) {
			return nil, errors.New("expected closing parenthesis after subquery")
		}
		
		return &Subquery{Select: subquery}, nil
	} else {
		// Parse as regular parenthesized expression
		tokenizer.PushBack()
		expr, err := parseExpr(tokenizer)
		if err != nil {
			return nil, err
		}
		
		tok, _ := tokenizer.Scan()
		if tok != int(RPAREN) {
			return nil, errors.New("expected closing parenthesis")
		}
		
		return &ParenExpr{Expr: expr}, nil
	}
}

// parseCaseExpr parses CASE expressions
func parseCaseExpr(tokenizer *Tokenizer) (Expr, error) {
	caseExpr := &CaseExpr{}
	
	// Check if this is a simple CASE or searched CASE
	tok, _ := tokenizer.Scan()
	if tok != int(WHEN) {
		// Simple CASE - has an expression after CASE
		tokenizer.PushBack()
		expr, err := parseExpr(tokenizer)
		if err != nil {
			return nil, err
		}
		caseExpr.Expr = expr
	} else {
		// Searched CASE - put back WHEN token
		tokenizer.PushBack()
	}
	
	// Parse WHEN clauses
	for {
		tok, _ := tokenizer.Scan()
		if tok != int(WHEN) {
			tokenizer.PushBack()
			break
		}
		
		when := &When{}
		cond, err := parseExpr(tokenizer)
		if err != nil {
			return nil, err
		}
		when.Cond = cond
		
		tok, _ = tokenizer.Scan()
		if tok != int(THEN) {
			return nil, errors.New("expected THEN after WHEN condition")
		}
		
		valExpr, err := parseExpr(tokenizer)
		if err != nil {
			return nil, err
		}
		when.Val = valExpr
		
		caseExpr.Whens = append(caseExpr.Whens, when)
	}
	
	// Parse optional ELSE clause
	tok, _ = tokenizer.Scan()
	if tok == int(ELSE) {
		elseExpr, err := parseExpr(tokenizer)
		if err != nil {
			return nil, err
		}
		caseExpr.Else = elseExpr
		tok, _ = tokenizer.Scan()
	}
	
	// Expect END
	if tok != int(END) {
		return nil, errors.New("expected END after CASE expression")
	}
	
	return caseExpr, nil
}

// parseBegin parses a BEGIN statement
func parseBegin(tokenizer *Tokenizer) (*BeginStatement, error) {
	return &BeginStatement{}, nil
}

// parseCommit parses a COMMIT statement
func parseCommit(tokenizer *Tokenizer) (*CommitStatement, error) {
	return &CommitStatement{}, nil
}

// parseRollback parses a ROLLBACK statement
func parseRollback(tokenizer *Tokenizer) (*RollbackStatement, error) {
	return &RollbackStatement{}, nil
}